package com.xu.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xu.base.enums.ResponseCodeEnum;
import com.xu.base.exception.ServiceException;
import com.xu.base.utils.AssertUtils;
import com.xu.minio.model.MinioFile;
import com.xu.minio.utils.MinioService;
import com.xu.system.model.convert.FileConvert;
import com.xu.system.model.entity.SysFile;
import com.xu.system.model.entity.SysFileData;
import com.xu.system.model.pojo.file.FileVo;
import com.xu.system.service.IFileService;
import com.xu.system.service.db.ISysFileDataService;
import com.xu.system.service.db.ISysFileService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 文件服务
 *
 * @Author: 许乾伟
 * @Date: 2024/12/17 15:19
 */
@Service
public class FileServiceImpl implements IFileService {
    @Resource
    private ISysFileService sysFileService;
    @Resource
    private ISysFileDataService sysFileDataService;
    @Resource
    MinioService minioService;
    @Resource
    FileConvert fileConvert;

    @Override
    public MinioFile uploadMinioFile(MultipartFile file) {
        try {
            MinioFile minioFile = minioService.uploadMultipartFile(file);
            SysFile sysFile = fileConvert.toSysFile(minioFile);
            boolean save = sysFileService.save(sysFile);
            AssertUtils.isFalse(save, ResponseCodeEnum.HANDEL_FAILED, "上传文件失败");
            minioFile.setFileId(sysFile.getId());
            return minioFile;
        } catch (Exception e) {
            throw new ServiceException(ResponseCodeEnum.HANDEL_FAILED,"上传文件失败");
        }
    }

    @Override
    public Boolean saveFileData(Long sourceId, String sourceCode, List<Long> fileIds) {
        sysFileDataService.remove(new QueryWrapper<SysFileData>().eq(SysFileData.SOURCE_ID, sourceId).eq(SysFileData.SOURCE_CODE, sourceCode));
        if (CollectionUtils.isEmpty(fileIds)){
            return true;
        }
        return sysFileDataService.saveBatch(fileIds.stream().map(fileId -> new SysFileData().setSourceId(sourceId).setSourceCode(sourceCode).setFileId(fileId)).collect(Collectors.toList()));
    }

    @Override
    public FileVo getOneFile(Long sourceId, String sourceCode) {
        List<FileVo> allFile = getAllFile(sourceId, sourceCode);
        if (CollectionUtils.isEmpty(allFile)){
            return null;
        }
        return allFile.get(0);
    }

    @Override
    public List<FileVo> getAllFile(Long sourceId, String sourceCode) {
        List<Long> fileIds = sysFileDataService.list(new QueryWrapper<SysFileData>()
                        .eq(SysFileData.SOURCE_ID, sourceId)
                        .eq(SysFileData.SOURCE_CODE, sourceCode))
                .stream().map(SysFileData::getFileId).collect(Collectors.toList());
        if (fileIds.isEmpty()){
            return null;
        }
        List<SysFile> list = sysFileService.list(new QueryWrapper<SysFile>()
                .in(SysFile.ID, fileIds));
        List<FileVo> result = fileConvert.toFileVoList(list);
        return result;
    }

    @Override
    public Map<Long, String> getFileMapBySourceIds(List<Long> sourceIds, String sourceCode) {
        if (CollectionUtils.isEmpty(sourceIds)){
            return new HashMap<>();
        }
        List<SysFileData> fileDatas = sysFileDataService.list(new QueryWrapper<SysFileData>()
                .in(SysFileData.SOURCE_ID, sourceIds)
                .eq(SysFileData.SOURCE_CODE, sourceCode));
        Map<Long,String> result = new HashMap<>();
        if (fileDatas.isEmpty()){
            return result;
        }
        List<Long> fileIds = fileDatas.stream().map(SysFileData::getFileId).collect(Collectors.toList());
        List<SysFile> files = sysFileService.list(new QueryWrapper<SysFile>()
                .in(SysFile.ID, fileIds));
        for (SysFileData sysFileData : fileDatas) {
            SysFile file = files.stream().filter(n -> n.getId().equals(sysFileData.getFileId())).findFirst().orElse(null);
            result.put(sysFileData.getSourceId(), file.getFilePath());
        }
        return result;
    }

    @Override
    public MinioFile uploadAndSaveFileData(Long sourceId, String sourceCode, MultipartFile file) {
        MinioFile minioFile = uploadMinioFile(file);
        saveFileData(sourceId, sourceCode, List.of(minioFile.getFileId()));
        return minioFile;
    }
}
